/*
 * Copyright (c) 2009-2013 EvTech Project
 * All rights reserved.
 * 
 * This file is part of LModeller.
 *
 * LModeller is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * LModeller is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LModeller.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package fi.honkalampisaatio.lmodeler.setup;

import javax.swing.JPanel;
import javax.swing.JLabel;

import java.awt.Color;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.factories.FormFactory;

import fi.honkalampisaatio.game.xml.KeyValuePair;
import fi.honkalampisaatio.game.xml.LanguageSettings;
import fi.honkalampisaatio.game.xml.SettingsReader;
import fi.honkalampisaatio.lmodeller.LanguageResource;
import fi.honkalampisaatio.lmodeller.LModeller;
import fi.honkalampisaatio.lmodeller.xml.GLSettings;
import fi.honkalampisaatio.lmodeller.xml.GameSettings;

import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JCheckBox;
import javax.xml.bind.JAXBException;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import javax.swing.ButtonGroup;
import javax.swing.SwingConstants;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

public class GameUIPanel extends JPanel implements ActionListener, ChangeListener {
	public final static String DEFAULT_ACTIONCOLOR = "#FFE3A1";
	public final static String DEFAULT_DIRECTIONCOLOR = "#6CE0D9";
	private JComboBox<String> cbFonts;
	private JButton btnDirectionColor;
	private JButton btnActionColor;
	private JCheckBox chckbxFullScreen;
	private JComboBox<LanguageSettings> cbLanguages;
	private JComboBox cbScreenResolution;
	private JLabel lblNewLabel;
	private JRadioButton rdbtnSpinner;
	private JRadioButton rdbtnTable;
	private JLabel lblColumns;
	private JLabel lblNewLabel_1;
	private JLabel lblNewLabel_2;
	private JSpinner spMinBlockCount;
	private JSpinner spColumnCount;
	private JSpinner spMaxBlockCount;
	private JCheckBox chckbxShowExit;

	/**
	 * Create the panel.
	 */
	public GameUIPanel() {
		setLayout(new FormLayout(new ColumnSpec[] {
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("max(50dlu;min):grow"),
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("50dlu:grow"),
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("50dlu:grow"),
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("max(50dlu;min):grow"),
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("max(50dlu;default):grow"),
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("max(50dlu;min):grow"),
				FormFactory.RELATED_GAP_COLSPEC,},
			new RowSpec[] {
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,}));
		
		JLabel lblFontName = new JLabel("Fontti");
		lblFontName.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(lblFontName, "2, 2, 5, 1, right, center");
		
		cbFonts = new JComboBox/*<String>*/(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
		cbFonts.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(cbFonts, "8, 2, 5, 1, fill, fill");
		cbFonts.addActionListener(this);
		
		btnActionColor = new JButton("Toimintaväri");
		btnActionColor.setFont(new Font("Tahoma", Font.PLAIN, 20));
		btnActionColor.addActionListener(this);
		btnActionColor.setBackground(Color.BLACK);
		btnActionColor.setForeground(Color.WHITE);
		
		btnDirectionColor = new JButton("Ohjeväri");
		btnDirectionColor.setFont(new Font("Tahoma", Font.PLAIN, 20));
		btnDirectionColor.addActionListener(this);
		btnDirectionColor.setBackground(Color.BLACK);
		btnDirectionColor.setForeground(Color.WHITE);
		add(btnDirectionColor, "8, 4, 5, 1, fill, fill");
		add(btnActionColor, "8, 6, 5, 1, fill, fill");
		
		JLabel lblLanguage = new JLabel("Kieli");
		lblLanguage.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(lblLanguage, "2, 8, 5, 1, right, default");

		File folder = new File(LModeller.LANGUAGEFOLDER);
		ArrayList<LanguageSettings> languages = new ArrayList<LanguageSettings>();
		if (folder.exists()) {
		    File[] listOfFiles = folder.listFiles();
		    for (int i = 0; i < listOfFiles.length; i++) {
			      if (listOfFiles[i].isFile()) {
			    	  String filename = listOfFiles[i].getName();
			    	  String ext = filename.substring(filename.lastIndexOf('.')+1,filename.length());
			    	if (ext.equalsIgnoreCase("xml") ) {  
			    		LanguageSettings ls = loadLanguageFile(listOfFiles[i].getPath());
			    		if(ls!=null)
			    		{
			    			languages.add(ls);
			    		}
			      	}
			      }
			    }
		}
		cbLanguages = new JComboBox/*<LanguageSettings>*/(languages.toArray(new LanguageSettings[languages.size()]));
		cbLanguages.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(cbLanguages, "8, 8, 5, 1, fill, fill");
		
		chckbxFullScreen = new JCheckBox("Koko näytön tila");
		chckbxFullScreen.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(chckbxFullScreen, "2, 10, 5, 1, center, fill");
		
		ArrayList<String> screenModes = new ArrayList<String>();
		try {
			DisplayMode[] modes = Display.getAvailableDisplayModes();
			for(int i=0; i<modes.length; i++)
			{
				screenModes.add(modes[i].getWidth() + "*" + modes[i].getHeight());
			}
		} catch (LWJGLException e) {
			e.printStackTrace();
		}
		
		chckbxShowExit = new JCheckBox("Näytä lopetuspainike");
		chckbxShowExit.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(chckbxShowExit, "8, 10, 5, 1, center, fill");
		
		JLabel lblScreenResolution = new JLabel("Näytön tarkkuus");
		lblScreenResolution.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(lblScreenResolution, "2, 12, 5, 1, right, default");
		
		cbScreenResolution = new JComboBox(screenModes.toArray());
		cbScreenResolution.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(cbScreenResolution, "8, 12, 5, 1, fill, fill");
		
		lblNewLabel = new JLabel("Palikoiden lukumäärän valitsin");
		lblNewLabel.setFont(new Font("Tahoma", Font.PLAIN, 20));
		lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
		add(lblNewLabel, "2, 16, 11, 1");
		
		rdbtnTable = new JRadioButton("Taulukko");
		rdbtnTable.addChangeListener(this);
		rdbtnTable.setHorizontalAlignment(SwingConstants.RIGHT);
		rdbtnTable.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(rdbtnTable, "2, 18, 5, 1");
		
		rdbtnSpinner = new JRadioButton("Pyörijä");
		rdbtnSpinner.addChangeListener(this);
		rdbtnSpinner.setHorizontalAlignment(SwingConstants.LEFT);
		rdbtnSpinner.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(rdbtnSpinner, "8, 18, 5, 1");
		
		lblColumns = new JLabel("Sarakkeet");
		lblColumns.setHorizontalAlignment(SwingConstants.RIGHT);
		lblColumns.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(lblColumns, "2, 20, right, default");
		
		spColumnCount = new JSpinner();
		spColumnCount.setFont(new Font("Tahoma", Font.PLAIN, 20));
		spColumnCount.addChangeListener(this);
		add(spColumnCount, "4, 20");
		
		lblNewLabel_1 = new JLabel("Minimi");
		lblNewLabel_1.setHorizontalAlignment(SwingConstants.RIGHT);
		lblNewLabel_1.setFont(new Font("Tahoma", Font.PLAIN, 20));
		add(lblNewLabel_1, "6, 20");
		
		spMinBlockCount = new JSpinner();
		spMinBlockCount.setFont(new Font("Tahoma", Font.PLAIN, 20));
		spMinBlockCount.addChangeListener(this);
		add(spMinBlockCount, "8, 20");
		
		lblNewLabel_2 = new JLabel("Maksimi");
		lblNewLabel_2.setFont(new Font("Tahoma", Font.PLAIN, 20));
		lblNewLabel_2.setHorizontalAlignment(SwingConstants.RIGHT);
		add(lblNewLabel_2, "10, 20");
		
		spMaxBlockCount = new JSpinner();
		spMaxBlockCount.setFont(new Font("Tahoma", Font.PLAIN, 20));
		spMaxBlockCount.addChangeListener(this);
		add(spMaxBlockCount, "12, 20");

	    ButtonGroup group = new ButtonGroup();
	    group.add(rdbtnSpinner);
	    group.add(rdbtnTable);
		rdbtnSpinner.setSelected(true);
		//rdbtnTable.setSelected(false);
		//spColumnCount.setEnabled(false);

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==cbFonts)
		{
			btnDirectionColor.setFont(new Font((String)cbFonts.getSelectedItem(), 
					btnDirectionColor.getFont().getStyle(), btnDirectionColor.getFont().getSize()));
			btnActionColor.setFont(new Font((String)cbFonts.getSelectedItem(), 
					btnActionColor.getFont().getStyle(), btnActionColor.getFont().getSize()));
		}

		if(e.getSource()==btnDirectionColor)
		{
			Color newDirColor = JColorChooser.showDialog(this, "Valitse ohjeväri", Color.decode(DEFAULT_DIRECTIONCOLOR));
			if(newDirColor!=null)
			{
				btnDirectionColor.setForeground(newDirColor);
			}
		}
		if(e.getSource()==btnActionColor)
		{
			Color newActionColor = JColorChooser.showDialog(this, "Valitse toimintaväri", Color.decode(DEFAULT_ACTIONCOLOR));
			if(newActionColor!=null)
			{
				btnActionColor.setForeground(newActionColor);
			}
		}
	}

	
	private LanguageSettings loadLanguageFile(String languageFile) {
		if(languageFile==null)
			return null;
		LanguageSettings languageSettings = null;
		try {
			languageSettings = (LanguageSettings) SettingsReader.getInstance().readSettings(
					languageFile, LanguageSettings.class);
		} catch (JAXBException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}

		Iterator<KeyValuePair> it = languageSettings.getValueList().iterator();
		while(it.hasNext()) {
			KeyValuePair value = it.next();
			LanguageResource lr = LanguageResource.getInstance();
			lr.setValue(value.getKey(), value.getValue());
		}
		return languageSettings;
	}

	public void setData(GameSettings gameSettings) {
		if(gameSettings.getGlSettings()!=null)
		{
			cbScreenResolution.setSelectedItem(gameSettings.getGlSettings().getDisplayWidth()+"*"+gameSettings.getGlSettings().getDisplayHeight());
			chckbxFullScreen.setSelected(gameSettings.getGlSettings().getFullScreen());
			chckbxShowExit.setSelected(gameSettings.getShowExit());
		}
		cbFonts.setSelectedItem(gameSettings.getFontName());
		btnDirectionColor.setFont(new Font((String)cbFonts.getSelectedItem(), 
				btnDirectionColor.getFont().getStyle(), btnDirectionColor.getFont().getSize()));
		try {
			Color dirColor = Color.decode(gameSettings.getDirectionColor());
			btnDirectionColor.setForeground(dirColor);
		}
		catch (Exception e)
		{
			Color dirColor = Color.decode(DEFAULT_DIRECTIONCOLOR);
			btnDirectionColor.setForeground(dirColor);
		}
		btnActionColor.setFont(new Font((String)cbFonts.getSelectedItem(), 
				btnActionColor.getFont().getStyle(), btnActionColor.getFont().getSize()));
		try {
			Color actionColor = Color.decode(gameSettings.getActionColor());
			btnActionColor.setForeground(actionColor);
		}
		catch (Exception e)
		{
			Color actionColor = Color.decode(DEFAULT_ACTIONCOLOR);
			btnActionColor.setForeground(actionColor);
		}
		for(int i=0; i<cbLanguages.getItemCount() && gameSettings.getLanguage()!=null; i++)
		{
			if(cbLanguages.getItemAt(i).getLanguage().equalsIgnoreCase(gameSettings.getLanguage()))
			{
				cbLanguages.setSelectedIndex(i);
			}
		}
		spMaxBlockCount.setValue(gameSettings.getMaxBlockCountInRandomMenu());
		spMinBlockCount.setValue(gameSettings.getMinBlockCountInRandomMenu());
		spColumnCount.setValue(gameSettings.getColumnCountInRandomMenu());
		if(gameSettings.getRandomMenuType()==GameSettings.RANDOMMENU_TYPE.TABLE)
		{
			rdbtnSpinner.setSelected(false);
			rdbtnTable.setSelected(true);
			spColumnCount.setEnabled(true);
		}
		else
		{
			rdbtnSpinner.setSelected(true);
			rdbtnTable.setSelected(false);
			spColumnCount.setEnabled(false);
		}
	}
	
	public GameSettings getData(GameSettings gameSettings)
	{
		try {
			gameSettings.setFontName((String)cbFonts.getSelectedItem());
			gameSettings.setActionColor(Integer.toHexString(btnActionColor.getForeground().getRGB()));
			gameSettings.setDirectionColor(Integer.toHexString(btnDirectionColor.getForeground().getRGB()));
			gameSettings.setLanguage(((LanguageSettings)cbLanguages.getSelectedItem()).getLanguage());
			GLSettings glS = new GLSettings();
			glS.setFullScreen(chckbxFullScreen.isSelected());
			gameSettings.setShowExit(chckbxShowExit.isSelected());
			String resolution = (String)cbScreenResolution.getSelectedItem();
			glS.setDisplayWidth(Integer.parseInt(resolution.substring(0, resolution.indexOf("*"))));
			glS.setDisplayHeight(Integer.parseInt(resolution.substring(resolution.indexOf("*")+1)));
			gameSettings.setGlSettings(glS);
			gameSettings.setMinBlockCountInRandomMenu((int)spMinBlockCount.getValue());
			gameSettings.setMaxBlockCountInRandomMenu((int)spMaxBlockCount.getValue());
			gameSettings.setColumnCountInRandomMenu((int)spColumnCount.getValue());
			
			if(rdbtnTable.isSelected())
			{
				gameSettings.setRandomMenuType(GameSettings.RANDOMMENU_TYPE.TABLE);
			}
			else
			{
				gameSettings.setRandomMenuType(GameSettings.RANDOMMENU_TYPE.SPINNER);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return gameSettings;
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		if(e.getSource()==spMaxBlockCount)
		{
			if((int)spMaxBlockCount.getValue()<(int)spMinBlockCount.getValue())
			{
				spMaxBlockCount.setValue(spMinBlockCount.getValue());
			}
		}
		if(e.getSource()==spMinBlockCount)
		{
			if((int)spMinBlockCount.getValue()<1)
			{
				spMinBlockCount.setValue(1);
			}
			if((int)spMinBlockCount.getValue()>(int)spMaxBlockCount.getValue())
			{
				spMaxBlockCount.setValue(spMinBlockCount.getValue());
			}
		}
		if(e.getSource()==spColumnCount)
		{
			if((int)spColumnCount.getValue()<1)
			{
				spColumnCount.setValue(1);
			}
			if((int)spColumnCount.getValue()>20)
			{
				spColumnCount.setValue(20);
			}
		}
		if(e.getSource()==rdbtnTable || e.getSource()==rdbtnSpinner)
		{
			if(rdbtnTable.isSelected())
				spColumnCount.setEnabled(true);
			else
				spColumnCount.setEnabled(false);
		}
	}
	
}
